home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / dev / gcc / ixemul_src.lha / ixemul-41.0 / library / socket.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  29KB  |  1,300 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  socket.c,v 1.1.1.1 1994/04/04 04:29:41 amiga Exp
  20.  *
  21.  *  socket.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:29:41  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  * Revision 1.2  1993/11/05  22:02:33  mwild
  26.  * inet.library code, plus NOT YET WORKING code for "own" sockets
  27.  *
  28.  */
  29.  
  30. #define KERNEL
  31. #include "ixemul.h"
  32. #include "kprintf.h"
  33.  
  34. #include <sys/socket.h>
  35. #include <sys/socketvar.h>
  36. #include <sys/ioctl.h>
  37. #include <net/if.h>
  38. #include <net/route.h>
  39. #include <netinet/in.h>
  40. #include "select.h"
  41. #include <machine/param.h>
  42.  
  43. #define static
  44. static struct file *getsock (int fdes);
  45. static int soo_read  (struct file *fp, char *buf, int len);
  46. static int soo_write (struct file *fp, char *buf, int len);
  47. static int soo_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data);
  48. static int soo_select(struct file *fp, int select_cmd, int io_mode);
  49. static int soo_close (struct file *fp);
  50.  
  51. /* inet.library is just as weird as ixemul.library... it takes all parameters
  52.    in parameter structures, addressed by d1 (a datareg taking an address..). */
  53. #include "inet.h"
  54.  
  55. int
  56. socket (int domain, int type, int protocol)
  57. {
  58.   struct a {
  59.           short   domain;
  60.           short   type;
  61.           short   protocol;
  62.           char    sigurg;
  63.           char    sigio;
  64.           short   err;
  65.           struct socket *so;
  66.   } uap;
  67.   struct socket *so;
  68.   struct file *fp;
  69.   struct user *p = &u;
  70.   int fd, err, ostat;
  71.  
  72.   if (domain == AF_INET && ! p->u_InetBase)
  73.     {
  74.       errno = ENOSYS;
  75.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  76.       return -1;
  77.     }
  78.  
  79.   ostat = p->p_stat;
  80.   p->p_stat = SWAIT;
  81.   do
  82.     {
  83.       if (err = falloc (&fp, &fd))
  84.         break;
  85.  
  86. #if defined (U_SOCKETS)
  87.       if (domain == AF_INET)
  88.     {
  89. #endif
  90.            uap.domain   = domain;
  91.            uap.type     = type;
  92.            uap.protocol = protocol;
  93.            uap.sigurg   = u.u_sigurg;
  94.            uap.sigio    = u.u_sigio;
  95.            uap.err      = 0;
  96.       
  97.        IN_socket(p->u_InetBase, &uap);
  98.            fp->f_so = uap.so;
  99.            err = uap.err;
  100. #if defined (U_SOCKETS)
  101.     }
  102.       else
  103.     {
  104.        err = socreate (domain, &so, type, protocol);
  105.     }
  106. #endif
  107.       if (err)
  108.     {
  109.       /* free the allocated fd */
  110.       p->u_ofile[fd] = 0;
  111.       fp->f_count = 0;
  112.           break;
  113.     }
  114.     
  115.       fp->f_stb.st_mode = 0666 | S_IFSOCK; /* not always, but.. */
  116.       fp->f_stb.st_size = 128;    /* sizeof mbuf. */
  117.       fp->f_stb.st_blksize = 128;
  118.  
  119.       fp->f_flags  = FREAD|FWRITE;
  120.       fp->f_type   = domain == AF_INET ? DTYPE_SOCKET : DTYPE_USOCKET;
  121.       fp->f_read   = soo_read;
  122.       fp->f_write  = soo_write;
  123.       fp->f_ioctl  = soo_ioctl;
  124.       fp->f_close  = soo_close;
  125.       fp->f_select = soo_select;
  126.     }
  127.   while (0);
  128.   if (CURSIG (p))
  129.     SetSignal (0, SIGBREAKF_CTRL_C);
  130.   p->p_stat = ostat;
  131.   if (err == EINTR)
  132.     setrun (FindTask (0));
  133.  
  134.   errno = err;
  135.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  136.   return err ? -1 : fd;
  137. }
  138.  
  139.  
  140. int
  141. bind (int s, caddr_t name, int namelen)
  142. {
  143.   struct a {
  144.           struct socket    *so;
  145.           caddr_t    name;
  146.           short        namelen;
  147.           short        err;
  148.   } uap;
  149.   register struct file *fp = getsock (s);
  150.   struct user *p = &u;
  151.   int ostat, error;
  152.  
  153.   if (! fp)
  154.     return -1;
  155.  
  156.   ostat = p->p_stat;
  157.   p->p_stat = SWAIT;
  158. #if defined (U_SOCKETS)
  159.   if (fp->f_type == DTYPE_SOCKET)
  160.     {
  161. #endif
  162.       uap.so      = fp->f_so;
  163.       uap.name    = name;
  164.       uap.namelen = namelen;
  165.       uap.err     = 0;
  166.   
  167.       IN_bind(p->u_InetBase, &uap);
  168.       error = uap.err;
  169. #if defined (U_SOCKETS)
  170.     }
  171.   else
  172.     {
  173.       struct mbuf *nam;
  174.       error = sockargs (&nam, name, namelen, MT_SONAME);
  175.       if (! error)
  176.     {
  177.           error = sobind (fp->f_so, nam);
  178.           m_freem (nam);
  179.         }
  180.     }
  181. #endif
  182.  
  183.   if (CURSIG (p))
  184.     SetSignal (0, SIGBREAKF_CTRL_C);
  185.   p->p_stat = ostat;
  186.   if (error == EINTR)
  187.     setrun (FindTask (0));
  188.   
  189.   errno = error;
  190.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  191.   return error ? -1 : 0;
  192. }
  193.  
  194. int
  195. listen (int s, int backlog)
  196. {
  197.   struct a {
  198.           struct socket *so;
  199.           short         backlog;
  200.           short         err;
  201.   } uap;
  202.   register struct file *fp = getsock (s);
  203.   struct user *p = &u;
  204.   int ostat, error;
  205.  
  206.   if (! fp)
  207.     return -1;
  208.  
  209.   ostat = p->p_stat;
  210.   p->p_stat = SWAIT;
  211.  
  212. #if defined (U_SOCKETS)
  213.   if (fp->f_type == DTYPE_SOCKET)
  214.     {
  215. #endif
  216.       uap.so      = fp->f_so;
  217.       uap.backlog = backlog;
  218.       uap.err     = 0;
  219.       IN_listen(p->u_InetBase, &uap);
  220.       error = uap.err;
  221. #if defined (U_SOCKETS)
  222.     }
  223.   else
  224.     {
  225.       error = solisten (fp->f_so, backlog);
  226.     }
  227. #endif
  228.   if (CURSIG (p))
  229.     SetSignal (0, SIGBREAKF_CTRL_C);
  230.   p->p_stat = ostat;
  231.   if (error == EINTR)
  232.     setrun (FindTask (0));
  233.  
  234.   errno = error;
  235.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  236.   return error ? -1 : 0;
  237. }
  238.  
  239. int
  240. accept (int s, caddr_t name, int *namelen)
  241. {
  242.   struct a {
  243.           struct socket *so;
  244.           caddr_t name;
  245.           short   namelen;
  246.           short   err;
  247.           struct socket *so2;
  248.   } uap;
  249.   struct file *fp = getsock (s), *fp2;
  250.   struct user *p = &u;
  251.   int err, fd2, ostat;
  252.   
  253.   if (! fp)
  254.     return -1;
  255.     
  256.   ostat = p->p_stat;
  257.   p->p_stat = SWAIT;
  258.   do
  259.     {
  260.       /* first try to get a new descriptor. If that fails, don't even
  261.          bother to call the library */
  262.       if (err = falloc (&fp2, &fd2))
  263.         break;
  264.       
  265. #if defined (U_SOCKETS)
  266.       if (fp->f_type == DTYPE_SOCKET)
  267.         {
  268. #endif
  269.           uap.so      = fp->f_so;
  270.           uap.name    = name;
  271.           uap.namelen = namelen ? *namelen : 0;
  272.           uap.so2      = 0;
  273.           uap.err     = 0;
  274.           IN_accept(p->u_InetBase, &uap);
  275.           if (! uap.so2 && !uap.err)
  276.             uap.err = EINTR;    /* XXX */
  277.       err = uap.err;
  278.           if (namelen)
  279.             *namelen = uap.namelen;
  280.  
  281.           fp2->f_so = uap.so2;
  282. #if defined (U_SOCKETS)
  283.     }
  284.       else
  285.         {
  286.       struct socket *so = fp->f_so;
  287.  
  288.           if ((so->so_options & SO_ACCEPTCONN) == 0) 
  289.             err = EINVAL;
  290.           else if ((so->so_state & SS_NBIO) && so->so_qlen == 0)
  291.         err = EWOULDBLOCK;
  292.       else
  293.         {
  294.           while (so->so_qlen == 0 && so->so_error == 0) 
  295.             {
  296.           if (so->so_state & SS_CANTRCVMORE) 
  297.             {
  298.               so->so_error = ECONNABORTED;
  299.               break;
  300.             }
  301.           if (err = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
  302.               netcon, 0))
  303.             {
  304.               so->so_error = err;
  305.               break;
  306.             }
  307.             }
  308.           if (so->so_error)
  309.             {
  310.               err = so->so_error;
  311.               so->so_error = 0;
  312.         }
  313.           else
  314.             {
  315.               struct socket *aso = so->so_q;
  316.               struct mbuf *nam;
  317.               if (soqremque (aso, 1) == 0)
  318.                 panic ("accept");
  319.               
  320.               fp2->f_so = aso;
  321.               nam = m_get (M_WAIT, MT_SONAME);
  322.               (void) soaccept (aso, nam);
  323.               if (name && namelen)
  324.                 {
  325.                   if (*namelen > nam->m_len)
  326.                     *namelen = nam->m_len;
  327.                   bcopy (mtod (nam, caddr_t), name, *namelen);
  328.                 }
  329.               m_freem (nam);
  330.             }
  331.         }
  332.         }
  333. #endif
  334.  
  335.       if (err)
  336.         {
  337.           /* free the second file */
  338.           u.u_ofile[fd2] = 0;
  339.           fp2->f_count = 0;
  340.           break;
  341.         }
  342.  
  343.     
  344.       fp2->f_stb.st_mode = 0666 | S_IFSOCK; /* not always, but.. */
  345.       fp2->f_stb.st_size = 128;    /* sizeof mbuf.. */
  346.       fp2->f_stb.st_blksize = 128;
  347.  
  348.       fp2->f_flags  = FREAD|FWRITE;
  349.       fp2->f_type   = DTYPE_SOCKET;
  350.       fp2->f_read   = soo_read;
  351.       fp2->f_write  = soo_write;
  352.       fp2->f_ioctl  = soo_ioctl;
  353.       fp2->f_close  = soo_close;
  354.       fp2->f_select = soo_select;
  355.     }
  356.   while (0);
  357.   if (CURSIG (p))
  358.     SetSignal (0, SIGBREAKF_CTRL_C);
  359.   p->p_stat = ostat;
  360.   if (err == EINTR)
  361.     setrun (FindTask (0));
  362.  
  363.   errno = err;
  364.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  365.   return err ? -1 : fd2;
  366. }
  367.  
  368.  
  369. int
  370. connect (int s, caddr_t name, int namelen)
  371. {
  372.   struct a {
  373.           struct socket *so;
  374.           caddr_t name;
  375.           short   namelen;
  376.           short   err;
  377.   } uap;
  378.   register struct file *fp = getsock (s);
  379.   struct user *p = &u;
  380.   int ostat, error;
  381.  
  382.   if (! fp)
  383.     return -1;
  384.  
  385.   ostat = p->p_stat;
  386.   p->p_stat = SWAIT;
  387.  
  388. #if defined (U_SOCKETS)
  389.   if (fp->f_type == DTYPE_SOCKET)
  390.     {
  391. #endif
  392.       uap.so      = fp->f_so;
  393.       uap.name    = name;
  394.       uap.namelen = namelen;
  395.       uap.err     = 0;
  396.       IN_connect(p->u_InetBase, &uap);
  397.       error = uap.err;
  398. #if defined (U_SOCKETS)
  399.     }
  400.   else
  401.     {
  402.       struct socket *so = fp->f_so;
  403.       struct mbuf *nam;
  404.  
  405.       if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
  406.         {
  407.       error = EALREADY;
  408.       break;
  409.     }
  410.       if (error = sockargs(&nam, name, namelen, MT_SONAME))
  411.     break;
  412.  
  413.       error = soconnect(so, nam);
  414.       if (error)
  415.     goto bad;
  416.       if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) 
  417.     {
  418.       m_freem(nam);
  419.       error = EINPROGRESS;
  420.     }
  421.  
  422.       Forbid ();
  423.       while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
  424.     if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
  425.                    netcon, 0))
  426.       break;
  427.       if (error == 0) 
  428.     {
  429.       error = so->so_error;
  430.       so->so_error = 0;
  431.     }
  432.       Permit ();
  433. bad:
  434.       so->so_state &= ~SS_ISCONNECTING;
  435.       m_freem(nam);
  436.       if (error == ERESTART)
  437.     error = EINTR;
  438.     }
  439. #endif
  440.  
  441.   if (CURSIG (p))
  442.     SetSignal (0, SIGBREAKF_CTRL_C);
  443.   p->p_stat = ostat;
  444.   if (error == EINTR)
  445.     setrun (FindTask (0));
  446.  
  447.   errno = error;
  448.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  449.   return error ? -1 : 0;
  450. }
  451.  
  452. #if 0
  453. /* This function is not available with Commodore sockets. */
  454.  
  455. int
  456. socketpair (int domain, int type, int protocol, int sv[2])
  457. {
  458.   register struct file *fp1, *fp2;
  459.   struct socket *so1, *so2;
  460.   struct user *p = &u;
  461.   int ostat, error;
  462.  
  463.   /* minimal test.. */
  464.   if (!sv[0] || !sv[1])
  465.     {
  466.       errno = EFAULT;
  467.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  468.       return -1;
  469.     }
  470.  
  471.   /* no go with Commo-sockets */
  472.   if (domain == AF_INET)
  473.     {
  474.       errno = EPFNOSUPPORT;
  475.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  476.       return -1;
  477.     }
  478.  
  479.   ostat = p->p_stat;
  480.   p->p_stat = SWAIT;
  481.   do
  482.     {
  483.       /* first try to allocate two descriptors */
  484.       if (error = falloc (&fp1, &sv[0]))
  485.         break;
  486.         
  487.       if (error = falloc (&fp2, &sv[1]))
  488.         {
  489. free_first:
  490.       /* free first descriptor */
  491.           u.u_ofile[sv[0]] = 0;
  492.           fp1->f_count = 0;
  493.           break;
  494.         }
  495.  
  496.       if (error = socreate(domain, &so1, type, protocol))
  497.         {
  498. free_second:
  499.           u.u_ofile[sv[1]] = 0;
  500.           fp2->f_count = 0;
  501.           goto free_first;
  502.         }
  503.  
  504.       if (error = socreate(domain, &so2, type, protocol))
  505.         {
  506. close_so1:
  507.       soclose (so1);
  508.           goto free_second;
  509.         }
  510.       
  511.       if (error = soconnect2(so1, so2))
  512.         {
  513. close_so2:
  514.       soclose (so2);
  515.       goto close_so1;
  516.     }
  517.        
  518.       if (type == SOCK_DGRAM) 
  519.     {
  520.       /*
  521.        * Datagram socket connection is asymmetric.
  522.        */
  523.       if (error = soconnect2(so2, so1))
  524.         goto close_so2;
  525.     }
  526.     }
  527.   while (0);
  528.   p->p_stat = ostat;
  529.  
  530.   if (error == EINTR)
  531.     setrun (FindTask (0));
  532.   
  533.   errno = error;
  534.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  535.   return error ? -1 : 0;
  536. }
  537. #endif
  538.  
  539.  
  540. int
  541. sendto (int s, caddr_t buf, int len, int flags, caddr_t to, int tolen)
  542. {
  543.   struct a {
  544.           struct socket *so;
  545.           caddr_t buf;
  546.           int     len;
  547.           short   flags;
  548.           caddr_t to;
  549.           short   tolen;
  550.           short   err;
  551.           int     rc;
  552.   } uap;
  553.   register struct file *fp = getsock (s);
  554.   struct user *p = &u;
  555.   int ostat;
  556.  
  557.   if (! fp)
  558.     return -1;
  559.  
  560.   ostat = p->p_stat;
  561.   p->p_stat = SWAIT;
  562.   uap.so    = fp->f_so;
  563.   uap.buf   = buf;
  564.   uap.len   = len;
  565.   uap.flags = flags;
  566.   uap.to    = to;
  567.   uap.tolen = tolen;
  568.   uap.err   = 0;
  569.   IN_sendto(p->u_InetBase, &uap);
  570.   if (CURSIG (p))
  571.     SetSignal (0, SIGBREAKF_CTRL_C);
  572.   p->p_stat = ostat;
  573.  
  574.   /* the library doesn't send this to us of course ;-) */
  575.   if (uap.err == EPIPE)
  576.     _psignal (FindTask (0), SIGPIPE);
  577.   if (uap.err == EINTR)
  578.     setrun (FindTask (0));
  579.   
  580.   errno = uap.err;
  581.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  582.   return uap.err ? -1 : uap.rc;
  583. }
  584.  
  585.  
  586. int
  587. send (int s, caddr_t buf, int len, int flags)
  588. {
  589.   struct a {
  590.           struct socket *so;
  591.           caddr_t buf;
  592.           int     len;
  593.           short   flags;
  594.           short   err;
  595.           int     rc;
  596.   } uap;
  597.   register struct file *fp = getsock (s);
  598.   struct user *p = &u;
  599.   int ostat;
  600.  
  601.   if (! fp)
  602.     return -1;
  603.  
  604.   ostat = p->p_stat;
  605.   p->p_stat = SWAIT;
  606.   uap.so    = fp->f_so;
  607.   uap.buf   = buf;
  608.   uap.len   = len;
  609.   uap.flags = flags;
  610.   uap.err   = 0;
  611.   IN_send (p->u_InetBase, &uap);
  612.   if (CURSIG (p))
  613.     SetSignal (0, SIGBREAKF_CTRL_C);
  614.   p->p_stat = ostat;
  615.   
  616.   /* the library doesn't send this to us of course ;-) */
  617.   if (uap.err == EPIPE)
  618.     _psignal (FindTask (0), SIGPIPE);
  619.   if (uap.err == EINTR)
  620.     setrun (FindTask (0));
  621.   
  622.   errno = uap.err;
  623.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  624.   return uap.err ? -1 : uap.rc;
  625. }
  626.  
  627.  
  628. int
  629. sendmsg (int s, caddr_t msg, int flags)
  630. {
  631.   struct a {
  632.           struct socket *so;
  633.           caddr_t msg;
  634.           short   flags;
  635.           short   err;
  636.           int     rc;
  637.   } uap;
  638.   register struct file *fp = getsock (s);
  639.   struct user *p = &u;
  640.   int ostat;
  641.  
  642.   if (! fp)
  643.     return -1;
  644.  
  645.   ostat = p->p_stat;
  646.   p->p_stat = SWAIT;
  647.   uap.so    = fp->f_so;
  648.   uap.msg   = msg;
  649.   uap.flags = flags;
  650.   uap.err   = 0;
  651.   IN_sendmsg (p->u_InetBase, &uap);
  652.   if (CURSIG (p))
  653.     SetSignal (0, SIGBREAKF_CTRL_C);
  654.   p->p_stat = ostat;
  655.   
  656.   /* the library doesn't send this to us of course ;-) */
  657.   if (uap.err == EPIPE)
  658.     _psignal (FindTask (0), SIGPIPE);
  659.   if (uap.err == EINTR)
  660.     setrun (FindTask (0));
  661.   
  662.   errno = uap.err;
  663.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  664.   return uap.err ? -1 : uap.rc;
  665. }
  666.  
  667.  
  668. int
  669. recvfrom (int s, caddr_t buf, int len, int flags, caddr_t from, int *fromlen)
  670. {
  671.   struct a {
  672.           struct socket *so;
  673.           caddr_t buf;
  674.           int     len;
  675.           short   flags;
  676.           caddr_t from;
  677.           short   fromlen;
  678.           short   err;
  679.           int     rc;
  680.   } uap;
  681.   register struct file *fp = getsock (s);
  682.   struct user *p = &u;
  683.   int ostat;
  684.  
  685.   if (! fp)
  686.     return -1;
  687.  
  688.   ostat = p->p_stat;
  689.   p->p_stat = SWAIT;
  690.   uap.so      = fp->f_so;
  691.   uap.buf     = buf;
  692.   uap.len     = len;
  693.   uap.flags   = flags;
  694.   uap.from    = from;
  695.   uap.fromlen = fromlen ? *fromlen : 0;
  696.   uap.err     = 0;
  697.   IN_recvfrom (p->u_InetBase, &uap);
  698.   if (CURSIG (p))
  699.     SetSignal (0, SIGBREAKF_CTRL_C);
  700.   p->p_stat = ostat;
  701.   if (uap.err == EINTR)
  702.     setrun (FindTask (0));
  703.   if (fromlen)
  704.     *fromlen = uap.fromlen;
  705.   
  706.   errno = uap.err;
  707.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  708.   return uap.err ? -1 : uap.rc;
  709. }
  710.  
  711.  
  712. int
  713. recv (int s, caddr_t buf, int len, int flags)
  714. {
  715.   struct a {
  716.           struct socket *so;
  717.           caddr_t buf;
  718.           int     len;
  719.           short   flags;
  720.           short   err;
  721.           int     rc;
  722.   } uap;
  723.   register struct file *fp = getsock (s);
  724.   struct user *p = &u;
  725.   int ostat;
  726.  
  727.   if (! fp)
  728.     return -1;
  729.  
  730.   ostat = p->p_stat;
  731.   p->p_stat = SWAIT;
  732.   uap.so    = fp->f_so;
  733.   uap.buf   = buf;
  734.   uap.len   = len;
  735.   uap.flags = flags;
  736.   uap.err   = 0;
  737.   IN_recv (p->u_InetBase, &uap);
  738.   if (CURSIG (p))
  739.     SetSignal (0, SIGBREAKF_CTRL_C);
  740.   p->p_stat = ostat;
  741.   if (uap.err == EINTR)
  742.     setrun (FindTask (0));
  743.   
  744.   errno = uap.err;
  745.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  746.   return uap.err ? -1 : uap.rc;
  747. }
  748.  
  749.  
  750. int
  751. recvmsg (int s, caddr_t msg, int flags)
  752. {
  753.   struct a {
  754.           struct socket *so;
  755.           caddr_t msg;
  756.           short   flags;
  757.           short   err;
  758.           int     rc;
  759.   } uap;
  760.   register struct file *fp = getsock (s);
  761.   struct user *p = &u;
  762.   int ostat;
  763.  
  764.   if (! fp)
  765.     return -1;
  766.  
  767.   ostat = p->p_stat;
  768.   p->p_stat = SWAIT;
  769.   uap.so    = fp->f_so;
  770.   uap.msg   = msg;
  771.   uap.flags = flags;
  772.   uap.err   = 0;
  773.   IN_recvmsg (p->u_InetBase, &uap);
  774.   if (CURSIG (p))
  775.     SetSignal (0, SIGBREAKF_CTRL_C);
  776.   p->p_stat = ostat;
  777.   if (uap.err == EINTR)
  778.     setrun (FindTask (0));
  779.   
  780.   errno = uap.err;
  781.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  782.   return uap.err ? -1 : uap.rc;
  783. }
  784.  
  785.  
  786. int
  787. shutdown (int s, int how)
  788. {
  789.   struct a {
  790.           struct socket *so;
  791.           short    how;
  792.           short    err;
  793.   } uap;
  794.   register struct file *fp = getsock (s);
  795.   struct user *p = &u;
  796.   int ostat;
  797.  
  798.   if (! fp)
  799.     return -1;
  800.  
  801.   ostat = p->p_stat;
  802.   p->p_stat = SWAIT;
  803.   uap.so  = fp->f_so;
  804.   uap.how = how;
  805.   uap.err = 0;
  806.   IN_shutdown (p->u_InetBase, &uap);
  807.   if (CURSIG (p))
  808.     SetSignal (0, SIGBREAKF_CTRL_C);
  809.   p->p_stat = ostat;
  810.   if (uap.err == EINTR)
  811.     setrun (FindTask (0));
  812.   
  813.   errno = uap.err;
  814.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  815.   return uap.err ? -1 : 0;
  816. }
  817.  
  818.  
  819. int
  820. setsockopt (int s, int level, int name, caddr_t val, int valsize)
  821. {
  822.   struct a {
  823.           struct socket *so;
  824.           short   level;
  825.           short   name;
  826.           caddr_t val;
  827.           short   valsize;
  828.           short   err;
  829.   } uap;
  830.   register struct file *fp = getsock (s);
  831.   struct user *p = &u;
  832.   int ostat;
  833.  
  834.   if (! fp)
  835.     return -1;
  836.  
  837.   ostat = p->p_stat;
  838.   p->p_stat = SWAIT;
  839.   uap.so      = fp->f_so;
  840.   uap.level   = level;
  841.   uap.name    = name;
  842.   uap.val     = val;
  843.   uap.valsize = valsize;
  844.   uap.err     = 0;
  845.   IN_setsockopt (p->u_InetBase, &uap);
  846.   if (CURSIG (p))
  847.     SetSignal (0, SIGBREAKF_CTRL_C);
  848.   p->p_stat = ostat;
  849.   if (uap.err == EINTR)
  850.     setrun (FindTask (0));
  851.  
  852.   errno = uap.err;
  853.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  854.   return uap.err ? -1 : 0;
  855. }
  856.  
  857.  
  858. int
  859. getsockopt (int s, int level, int name, caddr_t val, int *valsize)
  860. {
  861.   struct a {
  862.           struct socket *so;
  863.           short   level;
  864.           short   name;
  865.           caddr_t val;
  866.           short   valsize;
  867.           short   err;
  868.   } uap;
  869.   register struct file *fp = getsock (s);
  870.   struct user *p = &u;
  871.   int ostat;
  872.  
  873.   if (! fp)
  874.     return -1;
  875.  
  876.   ostat = p->p_stat;
  877.   p->p_stat = SWAIT;
  878.   uap.so      = fp->f_so;
  879.   uap.level   = level;
  880.   uap.name    = name;
  881.   uap.val     = val;
  882.   uap.valsize = valsize ? *valsize : 0;
  883.   uap.err     = 0;
  884.   IN_getsockopt (p->u_InetBase, &uap);
  885.   if (CURSIG (p))
  886.     SetSignal (0, SIGBREAKF_CTRL_C);
  887.   p->p_stat = ostat;
  888.   if (uap.err == EINTR)
  889.     setrun (FindTask (0));
  890.   if (valsize)
  891.     *valsize = uap.valsize;
  892.  
  893.   errno = uap.err;
  894.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  895.   return uap.err ? -1 : 0;
  896. }
  897.  
  898.  
  899. #if 0
  900. /* same problem as with socketpair() */
  901. pipe()
  902. {
  903.         register struct file *rf, *wf;
  904.         struct socket *rso, *wso;
  905.         int r;
  906.  
  907.         u.u_error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0);
  908.         if (u.u_error)
  909.                 return;
  910.         u.u_error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0);
  911.         if (u.u_error)
  912.                 goto free;
  913.         rf = falloc();
  914.         if (rf == NULL)
  915.                 goto free2;
  916.         r = u.u_r.r_val1;
  917.         rf->f_flag = FREAD;
  918.         rf->f_type = DTYPE_SOCKET;
  919.         rf->f_ops = &socketops;
  920.         rf->f_data = (caddr_t)rso;
  921.         wf = falloc();
  922.         if (wf == NULL)
  923.                 goto free3;
  924.         wf->f_flag = FWRITE;
  925.         wf->f_type = DTYPE_SOCKET;
  926.         wf->f_ops = &socketops;
  927.         wf->f_data = (caddr_t)wso;
  928.         u.u_r.r_val2 = u.u_r.r_val1;
  929.         u.u_r.r_val1 = r;
  930.         if (u.u_error = unp_connect2(wso, rso))
  931.                 goto free4;
  932.         wso->so_state |= SS_CANTRCVMORE;
  933.         rso->so_state |= SS_CANTSENDMORE;
  934.         return;
  935. free4:
  936.         wf->f_count = 0;
  937.         u.u_ofile[u.u_r.r_val2] = 0;
  938. free3:
  939.         rf->f_count = 0;
  940.         u.u_ofile[r] = 0;
  941. free2:
  942.         (void)soo_close(wso);
  943. free:
  944.         (void)soo_close(rso);
  945. }
  946. #endif
  947.  
  948.  
  949. /*
  950.  * Get socket name.
  951.  */
  952. int
  953. getsockname (int fdes, caddr_t asa, int *alen)
  954. {
  955.   struct a {
  956.           struct socket *so;
  957.           caddr_t asa;
  958.           short   alen;
  959.           short   err;
  960.   } uap;
  961.   register struct file *fp = getsock (fdes);
  962.   struct user *p = &u;
  963.   int ostat;
  964.  
  965.   if (! fp)
  966.     return -1;
  967.  
  968.   ostat = p->p_stat;
  969.   p->p_stat = SWAIT;
  970.   uap.so   = fp->f_so;
  971.   uap.asa  = asa;
  972.   uap.alen = alen ? *alen : 0;
  973.   uap.err  = 0;
  974.   IN_getsockname (p->u_InetBase, &uap);
  975.   if (CURSIG (p))
  976.     SetSignal (0, SIGBREAKF_CTRL_C);
  977.   p->p_stat = ostat;
  978.   if (uap.err == EINTR)
  979.     setrun (FindTask (0));
  980.   if (alen)
  981.     *alen = uap.alen;
  982.  
  983.   errno = uap.err;
  984.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  985.   return uap.err ? -1 : 0;
  986. }
  987.  
  988. /*
  989.  * Get name of peer for connected socket.
  990.  */
  991. int
  992. getpeername (int fdes, caddr_t asa, int *alen)
  993. {
  994.   struct a {
  995.           struct socket *so;
  996.           caddr_t asa;
  997.           short   alen;
  998.           short   err;
  999.   } uap;
  1000.   register struct file *fp = getsock (fdes);
  1001.   struct user *p = &u;
  1002.   int ostat;
  1003.  
  1004.   if (! fp)
  1005.     return -1;
  1006.  
  1007.   ostat = p->p_stat;
  1008.   p->p_stat = SWAIT;
  1009.   uap.so   = fp->f_so;
  1010.   uap.asa  = asa;
  1011.   uap.alen = alen ? *alen : 0;
  1012.   uap.err  = 0;
  1013.   IN_getpeername (p->u_InetBase, &uap);
  1014.   if (CURSIG (p))
  1015.     SetSignal (0, SIGBREAKF_CTRL_C);
  1016.   p->p_stat = ostat;
  1017.   if (uap.err == EINTR)
  1018.     setrun (FindTask (0));
  1019.   if (alen)
  1020.     *alen = uap.alen;
  1021.  
  1022.   errno = uap.err;
  1023.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1024.   return uap.err ? -1 : 0;
  1025. }
  1026.  
  1027. static struct file *
  1028. getsock (int fdes)
  1029. {
  1030.   register struct file *fp;
  1031.   register struct user *p = &u;
  1032.  
  1033.   if ((unsigned) fdes >= NOFILE)
  1034.     {
  1035.       errno = EBADF;
  1036.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1037.       return 0;
  1038.     }
  1039.  
  1040.   fp = p->u_ofile[fdes];
  1041.   if (fp == NULL)
  1042.     {
  1043.       errno = EBADF;
  1044.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1045.       return (0);
  1046.   }
  1047.   if (fp->f_type != DTYPE_SOCKET && fp->f_type != DTYPE_USOCKET) 
  1048.   {
  1049.       errno = ENOTSOCK;
  1050.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1051.       return (0);
  1052.     }
  1053.   if (fp->f_type == DTYPE_SOCKET && ! p->u_InetBase)
  1054.     {
  1055.       errno = EPIPE; /* ????? */
  1056.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1057.       return 0;
  1058.     }
  1059.   return (fp);
  1060. }
  1061.  
  1062.  
  1063. static int
  1064. soo_read (struct file *fp, char *buf, int len)
  1065. {
  1066.   struct a {
  1067.           struct socket *so;
  1068.           caddr_t buf;
  1069.           int     len;
  1070.           short   flags;
  1071.           short   err;
  1072.           int     rc;
  1073.   } uap;
  1074.   int ostat;
  1075.   struct user *p = &u;
  1076.  
  1077.   ostat = p->p_stat;
  1078.   p->p_stat = SWAIT;
  1079.   uap.so    = fp->f_so;
  1080.   uap.buf   = buf;
  1081.   uap.len   = len;
  1082.   uap.flags = 0;
  1083.   uap.err   = 0;
  1084.   IN_recv (p->u_InetBase, &uap);
  1085.   if (CURSIG (p))
  1086.     SetSignal (0, SIGBREAKF_CTRL_C);
  1087.   p->p_stat = ostat;
  1088.   if (uap.err == EINTR)
  1089.     setrun (FindTask (0));
  1090.   
  1091.   errno = uap.err;
  1092.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1093.   return uap.err ? -1 : uap.rc;
  1094. }
  1095.  
  1096.  
  1097. static int
  1098. soo_write (struct file *fp, char *buf, int len)
  1099. {
  1100.   struct a {
  1101.           struct socket *so;
  1102.           caddr_t buf;
  1103.           int     len;
  1104.           short   flags;
  1105.           short   err;
  1106.           int     rc;
  1107.   } uap;
  1108.   struct user *p = &u;
  1109.   int ostat;
  1110.  
  1111.   ostat = p->p_stat;
  1112.   p->p_stat = SWAIT;
  1113.   uap.so    = fp->f_so;
  1114.   uap.buf   = buf;
  1115.   uap.len   = len;
  1116.   uap.flags = 0;
  1117.   uap.err   = 0;
  1118.   IN_send (p->u_InetBase, &uap);
  1119.   if (CURSIG (p))
  1120.     SetSignal (0, SIGBREAKF_CTRL_C);
  1121.   p->p_stat = ostat;
  1122.   if (uap.err == EINTR)
  1123.     setrun (FindTask (0));
  1124.   
  1125.   errno = uap.err;
  1126.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1127.   return uap.err ? -1 : uap.rc;
  1128. }
  1129.  
  1130.  
  1131.  
  1132. static int
  1133. soo_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data)
  1134. {
  1135.   struct a {
  1136.           struct socket *so;
  1137.           short      cmd;
  1138.           caddr_t data;
  1139.           short   err;
  1140.   } uap;
  1141.   struct user *p = &u;
  1142.   int ostat;
  1143.  
  1144.   /* _SIGH_... they left almost everything neatly as it was in the BSD kernel
  1145.      code they used, but for whatever reason they decided they needed their
  1146.      own kind of ioctl encoding :-((
  1147.      
  1148.      Well then, here we go, and map `normal' cmds into CBM cmds: */
  1149.  
  1150.   switch (cmd)
  1151.    {
  1152.    case    SIOCADDRT    : cmd = ('r'<<8)|1; break;
  1153.    case    SIOCDELRT    : cmd = ('r'<<8)|2; break;
  1154.    case    SIOCSIFADDR    : cmd = ('i'<<8)|3; break;
  1155.    case    SIOCGIFADDR    : cmd = ('i'<<8)|4; break;
  1156.    case    SIOCSIFDSTADDR    : cmd = ('i'<<8)|5; break;
  1157.    case    SIOCGIFDSTADDR    : cmd = ('i'<<8)|6; break;
  1158.    case    SIOCSIFFLAGS    : cmd = ('i'<<8)|7; break;
  1159.    case    SIOCGIFFLAGS    : cmd = ('i'<<8)|8; break;
  1160.    case    SIOCGIFCONF    : cmd = ('i'<<8)|9; break;
  1161.    case    SIOCSIFMTU    : cmd = ('i'<<8)|10; break;
  1162.    case    SIOCGIFMTU    : cmd = ('i'<<8)|11; break;
  1163.    case    SIOCGIFBRDADDR    : cmd = ('i'<<8)|12; break;
  1164.    case    SIOCSIFBRDADDR    : cmd = ('i'<<8)|13; break;
  1165.    case    SIOCGIFNETMASK    : cmd = ('i'<<8)|14; break;
  1166.    case    SIOCSIFNETMASK    : cmd = ('i'<<8)|15; break;
  1167.    case    SIOCGIFMETRIC    : cmd = ('i'<<8)|16; break;
  1168.    case    SIOCSIFMETRIC    : cmd = ('i'<<8)|17; break;
  1169.    case SIOCSARP    : cmd = ('i'<<8)|18; break;
  1170.    case SIOCGARP    : cmd = ('i'<<8)|19; break;
  1171.    case SIOCDARP    : cmd = ('i'<<8)|20; break;
  1172.    case SIOCATMARK    : cmd = ('i'<<8)|21; break;
  1173.    case FIONBIO        : cmd = ('m'<<8)|22; break;
  1174.    case FIONREAD    : cmd = ('m'<<8)|23; break;
  1175.    case FIOASYNC    : cmd = ('m'<<8)|24; break;
  1176.    case SIOCSPGRP    : cmd = ('m'<<8)|25; break;
  1177.    case SIOCGPGRP    : cmd = ('m'<<8)|26; break;
  1178.    
  1179.    default:
  1180.      /* we really don't have to bother the library with cmds we can't even
  1181.         map over... */
  1182.      errno = EINVAL;
  1183.      KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1184.      return -1;
  1185.    }
  1186.  
  1187.   ostat = p->p_stat;
  1188.   p->p_stat = SWAIT;
  1189.   uap.so    = fp->f_so;
  1190.   uap.cmd   = cmd;
  1191.   uap.data  = data;
  1192.   uap.err   = 0;
  1193.   IN_ioctl (p->u_InetBase, &uap);
  1194.   if (CURSIG (p))
  1195.     SetSignal (0, SIGBREAKF_CTRL_C);
  1196.   p->p_stat = ostat;
  1197.   if (uap.err == EINTR)
  1198.     setrun (FindTask (0));
  1199.   
  1200.   errno = uap.err;
  1201.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1202.   return uap.err ? -1 : 0;
  1203. }
  1204.  
  1205.  
  1206. static int
  1207. soo_select (struct file *fp, int select_cmd, int io_mode)
  1208. {
  1209.   struct a {
  1210.           struct socket **sotable;  /* just one socket used */
  1211.       int      *inp;
  1212.       int      *out;
  1213.       int      *exc;
  1214.       void    *process;
  1215.       short      exec_sig;
  1216.       short      numfd;
  1217.       short   err;
  1218.       short   rc;
  1219.   } uap;
  1220.   int ostat;
  1221.   struct user *p = &u;
  1222.   int in, out, exc;
  1223.  
  1224.   switch (io_mode)
  1225.     {
  1226.     case SELMODE_IN:
  1227.       in = 1; out = 0; exc = 0;
  1228.       break;
  1229.     
  1230.     case SELMODE_OUT:
  1231.       in = 0; out = 1; exc = 0;
  1232.       break;
  1233.  
  1234.     case SELMODE_EXC:
  1235.       in = 0; out = 0; exc = 1;
  1236.       break;
  1237.     }
  1238.  
  1239.   ostat = p->p_stat;
  1240.   p->p_stat = SWAIT;
  1241.   uap.sotable = & fp->f_so;
  1242.   uap.inp = ∈
  1243.   uap.out = &out;
  1244.   uap.exc = &exc;
  1245. #if 0
  1246.   uap.process = FindTask (0);
  1247.   uap.exec_sig = p->u_sigio;
  1248. #else
  1249.   /* sigh, above doesn't work.. */
  1250.   uap.process = 0;
  1251.   uap.exec_sig = 0;
  1252. #endif
  1253.   uap.numfd = 1;
  1254.   uap.err = 0;
  1255.   IN_select (p->u_InetBase, &uap);
  1256.   if (CURSIG (p))
  1257.     SetSignal (0, SIGBREAKF_CTRL_C);
  1258.   p->p_stat = ostat;
  1259.       
  1260.   errno = uap.err;
  1261.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1262.   if (select_cmd == SELCMD_PREPARE)
  1263. #if 0
  1264.     return 1 << p->u_sigio;
  1265. #else
  1266.     return 0;
  1267. #endif
  1268.   else
  1269.     return uap.rc == 1 ? 1 : 0;
  1270. }
  1271.  
  1272.  
  1273. static int
  1274. soo_close (struct file *fp)
  1275. {
  1276.   struct a {
  1277.           struct socket *so;
  1278.       short   err;
  1279.   } uap;
  1280.   struct user *p = &u;
  1281.   int err = 0;
  1282.  
  1283.   ix_lock_base ();
  1284.   fp->f_count--;
  1285.   if (fp->f_count == 0)
  1286.     {
  1287.       /* don't have the base locked for IN_close, this MAY block!! */
  1288.       uap.so = fp->f_so;
  1289.       ix_unlock_base ();
  1290.       IN_close (p->u_InetBase, &uap);
  1291.       err = uap.err;
  1292.     }
  1293.   else
  1294.     ix_unlock_base ();
  1295.  
  1296.   errno = err;
  1297.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1298.   return err ? -1 : 0;
  1299. }
  1300.